<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 5.4.0">
  <link rel="apple-touch-icon" sizes="180x180" href="/blogwebpage/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/blogwebpage/images/favicon.ico">
  <link rel="icon" type="image/png" sizes="16x16" href="/blogwebpage/images/favicon.ico">
  <link rel="mask-icon" href="/blogwebpage/images/logo.svg" color="#222">
  <meta name="msvalidate.01" content="9BDlx6FiNE">

<link rel="stylesheet" href="/blogwebpage/css/main.css">


<link rel="stylesheet" href="/blogwebpage/lib/font-awesome/css/all.min.css">

<script id="hexo-configurations">
    var NexT = window.NexT || {};
    var CONFIG = {"hostname":"wangkejie.gitee.io","root":"/blogwebpage/","scheme":"Gemini","version":"7.8.0","exturl":true,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":true,"style":"default"},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":false,"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},"path":"search.xml"};
  </script>

  <meta name="description" content="书山有路勤为径，学海无涯苦作舟！">
<meta property="og:type" content="website">
<meta property="og:title" content="王科杰">
<meta property="og:url" content="https://wangkejie.gitee.io/blogwebpage/page/6/index.html">
<meta property="og:site_name" content="王科杰">
<meta property="og:description" content="书山有路勤为径，学海无涯苦作舟！">
<meta property="og:locale" content="zh_CN">
<meta property="article:author" content="Jack Wang">
<meta name="twitter:card" content="summary">

<link rel="canonical" href="https://wangkejie.gitee.io/blogwebpage/page/6/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome : true,
    isPost : false,
    lang   : 'zh-CN'
  };
</script>

  <title>王科杰 - Jack's Notes</title>
  


  <script>
    var _hmt = _hmt || [];
    (function() {
      var hm = document.createElement("script");
      hm.src = "https://hm.baidu.com/hm.js?93e26277de0cf2c5851167f2c6dcaa7d";
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(hm, s);
    })();
  </script>




  <noscript>
  <style>
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-header { opacity: initial; }

  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript>

</head>

<body itemscope itemtype="http://schema.org/WebPage">
  <div class="container use-motion">
    <div class="headband"></div>

    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏">
      <span class="toggle-line toggle-line-first"></span>
      <span class="toggle-line toggle-line-middle"></span>
      <span class="toggle-line toggle-line-last"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/blogwebpage/" class="brand" rel="start">
      <span class="logo-line-before"><i></i></span>
      <h1 class="site-title">王科杰</h1>
      <span class="logo-line-after"><i></i></span>
    </a>
      <p class="site-subtitle" itemprop="description">Jack's Notes</p>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
        <i class="fa fa-search fa-fw fa-lg"></i>
    </div>
  </div>
</div>




<nav class="site-nav">
  <ul id="menu" class="main-menu menu">
        <li class="menu-item menu-item-home">

    <a href="/blogwebpage/" rel="section"><i class="home fa-fw"></i>首页</a>

  </li>
        <li class="menu-item menu-item-archives">

    <a href="/blogwebpage/archives/" rel="section"><i class="archive fa-fw"></i>归档<span class="badge">52</span></a>

  </li>
        <li class="menu-item menu-item-about">

    <a href="/blogwebpage/me/" rel="section"><i class="user fa-fw"></i>关于</a>

  </li>
        <li class="menu-item menu-item-tags">

    <a href="/blogwebpage/tags/" rel="section"><i class="tags fa-fw"></i>标签<span class="badge">54</span></a>

  </li>
        <li class="menu-item menu-item-categories">

    <a href="/blogwebpage/categories/" rel="section"><i class="th fa-fw"></i>分类<span class="badge">56</span></a>

  </li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
        </a>
      </li>
  </ul>
</nav>



  <div class="search-pop-overlay">
    <div class="popup search-popup">
        <div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container">
    <input autocomplete="off" autocapitalize="off"
           placeholder="搜索..." spellcheck="false"
           type="search" class="search-input">
  </div>
  <span class="popup-btn-close">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div id="search-result">
  <div id="no-result">
    <i class="fa fa-spinner fa-pulse fa-5x fa-fw"></i>
  </div>
</div>

    </div>
  </div>

</div>
    </header>

    
  <div class="back-to-top">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>

  <span class="exturl github-corner" data-url="aHR0cHM6Ly9naXRodWIuY29tL0phY2stVmluZw==" title="Follow me on GitHub" aria-label="Follow me on GitHub"><svg width="80" height="80" viewBox="0 0 250 250" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></span>


    <main class="main">
      <div class="main-inner">
        <div class="content-wrap">
          

          <div class="content index posts-expand">
            
      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://wangkejie.gitee.io/blogwebpage/iOS/objective-c/index.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/blogwebpage/images/avatar.gif">
      <meta itemprop="name" content="Jack Wang">
      <meta itemprop="description" content="书山有路勤为径，学海无涯苦作舟！">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="王科杰">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          
            <a href="/blogwebpage/iOS/objective-c/index.html" class="post-title-link" itemprop="url">Objective-C 语言</a>
        </h2>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2015-07-10 12:24:27" itemprop="dateCreated datePublished" datetime="2015-07-10T12:24:27+08:00">2015-07-10</time>
            </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/blogwebpage/categories/iOS/" itemprop="url" rel="index"><span itemprop="name">iOS</span></a>
                </span>
                  ，
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/blogwebpage/categories/iOS/Objetive-C/" itemprop="url" rel="index"><span itemprop="name">Objetive-C</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <h2 id="苹果的源代码"><a href="#苹果的源代码" class="headerlink" title="苹果的源代码"></a>苹果的源代码</h2><p><span class="exturl" data-url="aHR0cHM6Ly9vcGVuc291cmNlLmFwcGxlLmNvbS90YXJiYWxscw==">https://openSource.apple.com/tarballs<i class="fa fa-external-link-alt"></i></span></p>
<h2 id="事件响应"><a href="#事件响应" class="headerlink" title="事件响应"></a>事件响应</h2><p>个人语言简述如下</p>
<ul>
<li>事件(例如点击屏幕)产生后，系统会把事件传递给当前的application，然后是window依次传递给viewcontroller，最后是手指所接触的view，</li>
<li>这个过程会被阻断，比如 userInteractionEnabled = NO,再比如隐藏 hidden = YES.透明度&lt;0.01,再比如指定了<code>hitTest：withEvent：</code>方法等。</li>
<li>然后，开始处理事件，view(UIResponder)来响应，view不处理，则上一级接受到继续，一直到application,这个过程重要的方法如下</li>
</ul>
<figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="regexp">//</span> 上一个响应者可能是父控件</span><br><span class="line">- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event&#123; </span><br><span class="line"><span class="regexp">//</span> 默认会把事件传递给上一个响应者,上一个响应者是父控件,交给父控件处理</span><br><span class="line"></span><br><span class="line"><span class="regexp">//</span>再比如自己处理完还想让父响应者也处理，就在这写一些东西</span><br><span class="line"><span class="regexp">//</span><span class="keyword">do</span> something here</span><br><span class="line"></span><br><span class="line">[super touchesBegan:touches withEvent:event]; </span><br><span class="line"><span class="regexp">//</span> 注意不是调用父控件的touches方法，而是调用父类的touches方法</span><br><span class="line"><span class="regexp">//</span> super是父类 superview是父控件 </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>


<h2 id="属性关键字"><a href="#属性关键字" class="headerlink" title="属性关键字"></a>属性关键字</h2><p>1.读写权限：readonly,readwrite(默认)<br>2.原子性: atomic(默认)，nonatomic。atomic读写线程安全，但效率低，而且不是绝对的安全，比如如果修饰的是数组，那么对数组的读写是安全的，但如果是操作数组进行添加移除其中对象的还，就不保证安全了。<br>3.引用计数：</p>
<ul>
<li>retain/strong</li>
<li>assign：修饰基本数据类型，修饰对象类型时，不改变其引用计数，会产生悬垂指针，修饰的对象在被释放后，assign指针仍然指向原对象内存地址，如果使用assign指针继续访问原对象的话，就可能会导致内存泄漏或程序异常</li>
<li>weak：不改变被修饰对象的引用计数，所指对象在被释放后，weak指针会自动置为nil</li>
<li>copy：分为深拷贝和浅拷贝<br>浅拷贝：对内存地址的复制，让目标对象指针和原对象指向同一片内存空间会增加引用计数<br>深拷贝：对对象内容的复制，开辟新的内存空间</li>
</ul>
<p>可变对象的copy和mutableCopy都是深拷贝<br>不可变对象的copy是浅拷贝，mutableCopy是深拷贝<br>copy方法返回的都是不可变对象</p>
<ul>
<li>@property (nonatomic, copy) NSMutableArray * array;这样写有什么影响？<br>因为copy方法返回的都是不可变对象，所以array对象实际上是不可变的，如果对其进行可变操作如添加移除对象，则会造成程序crash</li>
</ul>
<h2 id="KVO-Key-value-observing"><a href="#KVO-Key-value-observing" class="headerlink" title="KVO (Key-value observing)"></a>KVO (Key-value observing)</h2><p>KVO是观察者模式的另一实现。<br>使用了isa混写(isa-swizzling)来实现KVO</p>
<p>使用setter方法改变值KVO会生效，使用setValue:forKey即KVC改变值KVO也会生效，因为KVC会去调用setter方法</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">- (<span class="keyword">void</span>)<span class="attr">setValue:</span>(id)value</span><br><span class="line">&#123;</span><br><span class="line">    [self <span class="attr">willChangeValueForKey:</span>@<span class="string">&quot;key&quot;</span>];</span><br><span class="line">    </span><br><span class="line">    [<span class="built_in">super</span> <span class="attr">setValue:</span>value];</span><br><span class="line">    </span><br><span class="line">    [self <span class="attr">didChangeValueForKey:</span>@<span class="string">&quot;key&quot;</span>];</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<ul>
<li>那么通过直接赋值成员变量会触发KVO吗？<br>不会，因为不会调用setter方法，需要加上<br>willChangeValueForKey和didChangeValueForKey方法来手动触发才行</li>
</ul>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://wangkejie.gitee.io/blogwebpage/iOS/performance/index.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/blogwebpage/images/avatar.gif">
      <meta itemprop="name" content="Jack Wang">
      <meta itemprop="description" content="书山有路勤为径，学海无涯苦作舟！">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="王科杰">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          
            <a href="/blogwebpage/iOS/performance/index.html" class="post-title-link" itemprop="url">iOS性能优化</a>
        </h2>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2015-07-10 12:24:27" itemprop="dateCreated datePublished" datetime="2015-07-10T12:24:27+08:00">2015-07-10</time>
            </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/blogwebpage/categories/iOS/" itemprop="url" rel="index"><span itemprop="name">iOS</span></a>
                </span>
                  ，
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/blogwebpage/categories/iOS/iOS%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/" itemprop="url" rel="index"><span itemprop="name">iOS性能优化</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <h2 id="如何提升-tableview-的流畅度？"><a href="#如何提升-tableview-的流畅度？" class="headerlink" title="如何提升 tableview 的流畅度？"></a>如何提升 <code>tableview</code> 的流畅度？</h2><p>本质上是降低 CPU、GPU 的工作，从这两个大的方面去提升性能。</p>
<ul>
<li>CPU：对象的创建和销毁、对象属性的调整、布局计算、文本的计算和排版、图片的格式转换和解码、图像的绘制</li>
<li>GPU：纹理的渲染</li>
</ul>
<h3 id="卡顿优化在-CPU-层面"><a href="#卡顿优化在-CPU-层面" class="headerlink" title="卡顿优化在 CPU 层面"></a>卡顿优化在 CPU 层面</h3><ul>
<li>尽量用轻量级的对象，比如用不到事件处理的地方，可以考虑使用 CALayer 取代 UIView</li>
<li>不要频繁地调用 UIView 的相关属性，比如 frame、bounds、transform 等属性，尽量减少不必要的修改</li>
<li>尽量提前计算好布局，在有需要时一次性调整对应的属性，不要多次修改属性</li>
<li>Autolayout 会比直接设置 frame 消耗更多的 CPU 资源</li>
<li>图片的 size 最好刚好跟 UIImageView 的 size 保持一致</li>
<li>控制一下线程的最大并发数量</li>
<li>尽量把耗时的操作放到子线程<ul>
<li>文本处理（尺寸计算、绘制）</li>
<li>图片处理（解码、绘制）</li>
</ul>
</li>
</ul>
<h3 id="卡顿优化在-GPU层面"><a href="#卡顿优化在-GPU层面" class="headerlink" title="卡顿优化在 GPU层面"></a>卡顿优化在 GPU层面</h3><ul>
<li>尽量避免短时间内大量图片的显示，尽可能将多张图片合成一张进行显示</li>
<li>GPU能处理的最大纹理尺寸是 4096x4096，一旦超过这个尺寸，就会占用 CPU 资源进行处理，所以纹理尽量不要超过这个尺寸</li>
<li>尽量减少视图数量和层次</li>
<li>减少透明的视图（alpha&lt;1），不透明的就设置 opaque 为 YES</li>
<li>尽量避免出现离屏渲染</li>
</ul>
<p><span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmliaXJlbWUuY29tLzIwMTUvMTEvMTIvc21vb3RoX3VzZXJfaW50ZXJmYWNlc19mb3JfaW9zLw==">iOS 保持界面流畅的技巧<i class="fa fa-external-link-alt"></i></span></p>
<h4 id="1-预排版，提前计算"><a href="#1-预排版，提前计算" class="headerlink" title="1.预排版，提前计算"></a>1.预排版，提前计算</h4><p>在接收到服务端返回的数据后，尽量将 <code>CoreText</code> 排版的结果、单个控件的高度、<code>cell</code> 整体的高度提前计算好，将其存储在模型的属性中。需要使用时，直接从模型中往外取，避免了计算的过程。</p>
<p>尽量少用 <code>UILabel</code>，可以使用 <code>CALayer</code> 。避免使用 <code>AutoLayout</code> 的自动布局技术，采取纯代码的方式 </p>
<blockquote>
<p>Autolayout 是苹果本身提倡的技术，在大部分情况下也能很好的提升开发效率，但是 Autolayout 对于复杂视图来说常常会产生严重的性能问题。随着视图数量的增长，Autolayout 带来的 CPU 消耗会呈指数级上升。具体数据可以看这个文章：<span class="exturl" data-url="aHR0cDovL3BpbGt5Lm1lLzM2LyVFMyU4MCU4Mg==">http://pilky.me/36/。<i class="fa fa-external-link-alt"></i></span> 如果你不想手动调整 frame 等属性，你可以用一些工具方法替代（比如常见的 left/right/top/bottom/width/height 快捷属性），或者使用 ComponentKit、<a href="./iOS/thirdpart/asdk.html">AsyncDisplayKit</a> 等框架。</p>
</blockquote>
<h4 id="2-预渲染，提前绘制"><a href="#2-预渲染，提前绘制" class="headerlink" title="2.预渲染，提前绘制"></a>2.预渲染，提前绘制</h4><p>例如圆形的图标可以提前在，在接收到网络返回数据时，在后台线程进行处理，直接存储在模型数据里，回到主线程后直接调用就可以了</p>
<p>避免使用 CALayer 的 Border、corner、shadow、mask 等技术，这些都会触发离屏渲染。</p>
<h4 id="3-异步绘制"><a href="#3-异步绘制" class="headerlink" title="3.异步绘制"></a>3.异步绘制</h4><h4 id="4-全局并发线程"><a href="#4-全局并发线程" class="headerlink" title="4.全局并发线程"></a>4.全局并发线程</h4><h4 id="5-高效的图片异步加载"><a href="#5-高效的图片异步加载" class="headerlink" title="5.高效的图片异步加载"></a>5.高效的图片异步加载</h4><h2 id="如何有效降低-APP-包的大小？"><a href="#如何有效降低-APP-包的大小？" class="headerlink" title="如何有效降低 APP 包的大小？"></a>如何有效降低 <code>APP</code> 包的大小？</h2><p>降低包大小需要从两方面着手</p>
<h3 id="可执行文件"><a href="#可执行文件" class="headerlink" title="可执行文件"></a>可执行文件</h3><ul>
<li><p>编译器优化</p>
<ul>
<li>Strip Linked Product、Make Strings Read-Only、Symbols Hidden by Default 设置为 YES</li>
<li>去掉异常支持，Enable C++ Exceptions、Enable Objective-C Exceptions 设置为 NO， Other C Flags 添加 -fno-exceptions   </li>
</ul>
</li>
<li><p>利用 AppCode 检测未使用的代码：菜单栏 -&gt; Code -&gt; Inspect Code</p>
</li>
<li><p>编写LLVM插件检测出重复代码、未被调用的代码</p>
</li>
</ul>
<h3 id="资源"><a href="#资源" class="headerlink" title="资源"></a>资源</h3><blockquote>
<p>资源包括 图片、音频、视频 等</p>
</blockquote>
<ul>
<li>优化的方式可以对资源进行无损的压缩</li>
<li>去除没有用到的资源： <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3RpbnltaW5kL0xTVW51c2VkUmVzb3VyY2Vz">https://github.com/tinymind/LSUnusedResources<i class="fa fa-external-link-alt"></i></span></li>
</ul>
<h2 id="继续优化"><a href="#继续优化" class="headerlink" title="继续优化"></a>继续优化</h2><h3 id="1、重用和延迟加载-lazy-load-Views"><a href="#1、重用和延迟加载-lazy-load-Views" class="headerlink" title="1、重用和延迟加载(lazy load) Views"></a>1、重用和延迟加载(lazy load) Views</h3><ul>
<li>更多的view意味着更多的渲染，也就是更多的CPU和内存消耗，对于那种嵌套了很多view在UIScrollView里边的app更是如此。</li>
<li>这里我们用到的技巧就是模仿UITableView和UICollectionView的操作: 不要一次创建所有的subview，而是当需要时才创建，当它们完成了使命，把他们放进一个可重用的队列中。这样的话你就只需要在滚动发生时创建你的views，避免了不划算的内存分配。</li>
</ul>
<h3 id="2、Cache-Cache-还是Cache"><a href="#2、Cache-Cache-还是Cache" class="headerlink" title="2、Cache, Cache, 还是Cache!"></a>2、Cache, Cache, 还是Cache!</h3><ul>
<li>一个极好的原则就是，缓存所需要的，也就是那些不大可能改变但是需要经常读取的东西。</li>
<li>我们能缓存些什么呢？一些选项是，远端服务器的响应，图片，甚至计算结果，比如UITableView的行高。</li>
<li>NSCache和NSDictionary类似，不同的是系统回收内存的时候它会自动删掉它的内容。</li>
</ul>
<h3 id="3、权衡渲染方法-性能能还是要bundle保持合适的大小。"><a href="#3、权衡渲染方法-性能能还是要bundle保持合适的大小。" class="headerlink" title="3、权衡渲染方法.性能能还是要bundle保持合适的大小。"></a>3、权衡渲染方法.性能能还是要bundle保持合适的大小。</h3><h3 id="4、处理内存警告-移除对缓存，图片object和其他一些可以重创建的objects的strong-references"><a href="#4、处理内存警告-移除对缓存，图片object和其他一些可以重创建的objects的strong-references" class="headerlink" title="4、处理内存警告.移除对缓存，图片object和其他一些可以重创建的objects的strong references."></a>4、处理内存警告.移除对缓存，图片object和其他一些可以重创建的objects的strong references.</h3><h3 id="5、重用大开销对象"><a href="#5、重用大开销对象" class="headerlink" title="5、重用大开销对象"></a>5、重用大开销对象</h3><h3 id="6、一些objects的初始化很慢，比如NSDateFormatter和NSCalendar。然而，你又不可避免地需要使用它们，比如从JSON或者XML中解析数据。想要避免使用这个对象的瓶颈你就需要重用他们，可以通过添加属性到你的class里或者创建静态变量来实现。"><a href="#6、一些objects的初始化很慢，比如NSDateFormatter和NSCalendar。然而，你又不可避免地需要使用它们，比如从JSON或者XML中解析数据。想要避免使用这个对象的瓶颈你就需要重用他们，可以通过添加属性到你的class里或者创建静态变量来实现。" class="headerlink" title="6、一些objects的初始化很慢，比如NSDateFormatter和NSCalendar。然而，你又不可避免地需要使用它们，比如从JSON或者XML中解析数据。想要避免使用这个对象的瓶颈你就需要重用他们，可以通过添加属性到你的class里或者创建静态变量来实现。"></a>6、一些objects的初始化很慢，比如NSDateFormatter和NSCalendar。然而，你又不可避免地需要使用它们，比如从JSON或者XML中解析数据。想要避免使用这个对象的瓶颈你就需要重用他们，可以通过添加属性到你的class里或者创建静态变量来实现。</h3><h3 id="7、避免反复处理数据-在服务器端和客户端使用相同的数据结构很重要。"><a href="#7、避免反复处理数据-在服务器端和客户端使用相同的数据结构很重要。" class="headerlink" title="7、避免反复处理数据.在服务器端和客户端使用相同的数据结构很重要。"></a>7、避免反复处理数据.在服务器端和客户端使用相同的数据结构很重要。</h3><h3 id="8、选择正确的数据格式-解析JSON会比XML更快一些，JSON也通常更小更便于传输。从iOS5起有了官方内建的JSON-deserialization-就更加方便使用了。但是XML也有XML的好处，比如使用SAX-来解析XML就像解析本地文件一样，你不需像解析json一样等到整个文档下载完成才开始解析。当你处理很大的数据的时候就会极大地减低内存消耗和增加性能。"><a href="#8、选择正确的数据格式-解析JSON会比XML更快一些，JSON也通常更小更便于传输。从iOS5起有了官方内建的JSON-deserialization-就更加方便使用了。但是XML也有XML的好处，比如使用SAX-来解析XML就像解析本地文件一样，你不需像解析json一样等到整个文档下载完成才开始解析。当你处理很大的数据的时候就会极大地减低内存消耗和增加性能。" class="headerlink" title="8、选择正确的数据格式.解析JSON会比XML更快一些，JSON也通常更小更便于传输。从iOS5起有了官方内建的JSON deserialization 就更加方便使用了。但是XML也有XML的好处，比如使用SAX 来解析XML就像解析本地文件一样，你不需像解析json一样等到整个文档下载完成才开始解析。当你处理很大的数据的时候就会极大地减低内存消耗和增加性能。"></a>8、选择正确的数据格式.解析JSON会比XML更快一些，JSON也通常更小更便于传输。从iOS5起有了官方内建的JSON deserialization 就更加方便使用了。但是XML也有XML的好处，比如使用SAX 来解析XML就像解析本地文件一样，你不需像解析json一样等到整个文档下载完成才开始解析。当你处理很大的数据的时候就会极大地减低内存消耗和增加性能。</h3><h3 id="9、正确设定背景图片"><a href="#9、正确设定背景图片" class="headerlink" title="9、正确设定背景图片"></a>9、正确设定背景图片</h3><ul>
<li>全屏背景图，在view中添加一个UIImageView作为一个子View</li>
<li>只是某个小的view的背景图，你就需要用UIColor的colorWithPatternImage来做了，它会更快地渲染也不会花费很多内存：</li>
</ul>
<h3 id="10、减少使用Web特性。想要更高的性能你就要调整下你的HTML了。第一件要做的事就是尽可能移除不必要的javascript，避免使用过大的框架。能只用原生js就更好了。尽可能异步加载例如用户行为统计script这种不影响页面表达的javascript。注意你使用的图片，保证图片的符合你使用的大小。"><a href="#10、减少使用Web特性。想要更高的性能你就要调整下你的HTML了。第一件要做的事就是尽可能移除不必要的javascript，避免使用过大的框架。能只用原生js就更好了。尽可能异步加载例如用户行为统计script这种不影响页面表达的javascript。注意你使用的图片，保证图片的符合你使用的大小。" class="headerlink" title="10、减少使用Web特性。想要更高的性能你就要调整下你的HTML了。第一件要做的事就是尽可能移除不必要的javascript，避免使用过大的框架。能只用原生js就更好了。尽可能异步加载例如用户行为统计script这种不影响页面表达的javascript。注意你使用的图片，保证图片的符合你使用的大小。"></a>10、减少使用Web特性。想要更高的性能你就要调整下你的HTML了。第一件要做的事就是尽可能移除不必要的javascript，避免使用过大的框架。能只用原生js就更好了。尽可能异步加载例如用户行为统计script这种不影响页面表达的javascript。注意你使用的图片，保证图片的符合你使用的大小。</h3><h3 id="11、Shadow-Path-。CoreAnimation不得不先在后台得出你的图形并加好阴影然后才渲染，这开销是很大的。使用shadowPath的话就避免了这个问题。使用shadow-path的话iOS就不必每次都计算如何渲染，它使用一个预先计算好的路径。但问题是自己计算path的话可能在某些View中比较困难，且每当view的frame变化的时候你都需要去update-shadow-path"><a href="#11、Shadow-Path-。CoreAnimation不得不先在后台得出你的图形并加好阴影然后才渲染，这开销是很大的。使用shadowPath的话就避免了这个问题。使用shadow-path的话iOS就不必每次都计算如何渲染，它使用一个预先计算好的路径。但问题是自己计算path的话可能在某些View中比较困难，且每当view的frame变化的时候你都需要去update-shadow-path" class="headerlink" title="11、Shadow Path 。CoreAnimation不得不先在后台得出你的图形并加好阴影然后才渲染，这开销是很大的。使用shadowPath的话就避免了这个问题。使用shadow path的话iOS就不必每次都计算如何渲染，它使用一个预先计算好的路径。但问题是自己计算path的话可能在某些View中比较困难，且每当view的frame变化的时候你都需要去update shadow path."></a>11、Shadow Path 。CoreAnimation不得不先在后台得出你的图形并加好阴影然后才渲染，这开销是很大的。使用shadowPath的话就避免了这个问题。使用shadow path的话iOS就不必每次都计算如何渲染，它使用一个预先计算好的路径。但问题是自己计算path的话可能在某些View中比较困难，且每当view的frame变化的时候你都需要去update shadow path.</h3><h3 id="12、优化Table-View"><a href="#12、优化Table-View" class="headerlink" title="12、优化Table View"></a>12、优化Table View</h3><ul>
<li>正确使用reuseIdentifier来重用cells</li>
<li>尽量使所有的view opaque，包括cell自身</li>
<li>避免渐变，图片缩放，后台选人</li>
<li>缓存行高</li>
<li>如果cell内现实的内容来自web，使用异步加载，缓存请求结果</li>
<li>使用shadowPath来画阴影</li>
<li>减少subviews的数量</li>
<li>尽量不适用cellForRowAtIndexPath:，如果你需要用到它，只用-一次然后缓存结果</li>
<li>使用正确的数据结构来存储数据</li>
<li>使用rowHeight, sectionFooterHeight 和 sectionHeaderHeight来设定固定的高，不要请求delegate</li>
</ul>
<h3 id="13、选择正确的数据存储选项"><a href="#13、选择正确的数据存储选项" class="headerlink" title="13、选择正确的数据存储选项"></a>13、选择正确的数据存储选项</h3><ul>
<li>NSUserDefaults的问题是什么？虽然它很nice也很便捷，但是它只适用于小数据，比如一些简单的布尔型的设置选项，再大点你就要考虑其它方式了</li>
<li>XML这种结构化档案呢？总体来说，你需要读取整个文件到内存里去解析，这样是很不经济的。使用SAX又是一个很麻烦的事情。</li>
<li>NSCoding？不幸的是，它也需要读写文件，所以也有以上问题。</li>
<li>在这种应用场景下，使用SQLite 或者 Core Data比较好。使用这些技术你用特定的查询语句就能只加载你需要的对象。</li>
<li>在性能层面来讲，SQLite和Core Data是很相似的。他们的不同在于具体使用方法。</li>
<li>Core Data代表一个对象的graph model，但SQLite就是一个DBMS。</li>
<li>Apple在一般情况下建议使用Core Data，但是如果你有理由不使用它，那么就去使用更加底层的SQLite吧。</li>
<li>如果你使用SQLite，你可以用FMDB这个库来简化SQLite的操作，这样你就不用花很多经历了解SQLite的C API了。</li>
</ul>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  


  
  <nav class="pagination">
    <a class="extend prev" rel="prev" href="/blogwebpage/page/5/"><i class="fa fa-angle-left" aria-label="上一页"></i></a><a class="page-number" href="/blogwebpage/">1</a><span class="space">&hellip;</span><a class="page-number" href="/blogwebpage/page/5/">5</a><span class="page-number current">6</span>
  </nav>



          </div>
          

<script>
  window.addEventListener('tabs:register', () => {
    let { activeClass } = CONFIG.comments;
    if (CONFIG.comments.storage) {
      activeClass = localStorage.getItem('comments_active') || activeClass;
    }
    if (activeClass) {
      let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
      if (activeTab) {
        activeTab.click();
      }
    }
  });
  if (CONFIG.comments.storage) {
    window.addEventListener('tabs:click', event => {
      if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
      let commentClass = event.target.classList[1];
      localStorage.setItem('comments_active', commentClass);
    });
  }
</script>

        </div>
          
  
  <div class="toggle sidebar-toggle">
    <span class="toggle-line toggle-line-first"></span>
    <span class="toggle-line toggle-line-middle"></span>
    <span class="toggle-line toggle-line-last"></span>
  </div>

  <aside class="sidebar">
    <div class="sidebar-inner">

      <ul class="sidebar-nav motion-element">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <!--noindex-->
      <div class="post-toc-wrap sidebar-panel">
      </div>
      <!--/noindex-->

      <div class="site-overview-wrap sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="Jack Wang"
      src="/blogwebpage/images/avatar.gif">
  <p class="site-author-name" itemprop="name">Jack Wang</p>
  <div class="site-description" itemprop="description">书山有路勤为径，学海无涯苦作舟！</div>
</div>
<div class="site-state-wrap motion-element">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/blogwebpage/archives/">
        
          <span class="site-state-item-count">52</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
            <a href="/blogwebpage/categories/">
          
        <span class="site-state-item-count">56</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
            <a href="/blogwebpage/tags/">
          
        <span class="site-state-item-count">54</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>
  <div class="links-of-author motion-element">
      <span class="links-of-author-item">
        <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL0phY2stVmluZw==" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;Jack-Ving"><i class="github fa-fw"></i>GitHub</span>
      </span>
      <span class="links-of-author-item">
        <span class="exturl" data-url="bWFpbHRvOjcyNzg4MTk0NUBxcS5jb20=" title="E-Mail → mailto:727881945@qq.com"><i class="envelope fa-fw"></i>E-Mail</span>
      </span>
  </div>



      </div>

    </div>
  </aside>
  <div id="sidebar-dimmer"></div>


      </div>
    </main>

    <footer class="footer">
      <div class="footer-inner">
        

        
  <div class="beian"><span class="exturl" data-url="aHR0cHM6Ly9iZWlhbi5taWl0Lmdvdi5jbg==">京ICP备16036665号-2 </span>
  </div>

<div class="copyright">
  
  &copy; 
  <span itemprop="copyrightYear">2021</span>
  <span class="with-love">
    <i class="heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">Jack Wang</span>
</div>
  <div class="powered-by">由 <span class="exturl theme-link" data-url="aHR0cHM6Ly9oZXhvLmlv">Hexo</span> & <span class="exturl theme-link" data-url="aHR0cHM6Ly90aGVtZS1uZXh0Lm9yZw==">NexT.Gemini</span> 强力驱动
  </div>

        


  <div style="display: none;">
    <script src="//s95.cnzz.com/z_stat.php?id=1277804316&web_id=1277804316"></script>
  </div>






      </div>
    </footer>
  </div>

  
  <script src="/blogwebpage/lib/anime.min.js"></script>
  <script src="/blogwebpage/lib/velocity/velocity.min.js"></script>
  <script src="/blogwebpage/lib/velocity/velocity.ui.min.js"></script>

<script src="/blogwebpage/js/utils.js"></script>

<script src="/blogwebpage/js/motion.js"></script>


<script src="/blogwebpage/js/schemes/pisces.js"></script>


<script src="/blogwebpage/js/next-boot.js"></script>




  
  <script>
    (function(){
      var canonicalURL, curProtocol;
      //Get the <link> tag
      var x=document.getElementsByTagName("link");
		//Find the last canonical URL
		if(x.length > 0){
			for (i=0;i<x.length;i++){
				if(x[i].rel.toLowerCase() == 'canonical' && x[i].href){
					canonicalURL=x[i].href;
				}
			}
		}
    //Get protocol
	    if (!canonicalURL){
	    	curProtocol = window.location.protocol.split(':')[0];
	    }
	    else{
	    	curProtocol = canonicalURL.split(':')[0];
	    }
      //Get current URL if the canonical URL does not exist
	    if (!canonicalURL) canonicalURL = window.location.href;
	    //Assign script content. Replace current URL with the canonical URL
      !function(){var e=/([http|https]:\/\/[a-zA-Z0-9\_\.]+\.baidu\.com)/gi,r=canonicalURL,t=document.referrer;if(!e.test(r)){var n=(String(curProtocol).toLowerCase() === 'https')?"https://sp0.baidu.com/9_Q4simg2RQJ8t7jm9iCKT-xh_/s.gif":"//api.share.baidu.com/s.gif";t?(n+="?r="+encodeURIComponent(document.referrer),r&&(n+="&l="+r)):r&&(n+="?l="+r);var i=new Image;i.src=n}}(window);})();
  </script>




  
<script src="/blogwebpage/js/local-search.js"></script>













  

  
  <script src="//cdn.jsdelivr.net/npm/quicklink@1/dist/quicklink.umd.js"></script>
  <script>
      window.addEventListener('load', () => {
      quicklink({
        timeout : 3000,
        priority: true,
        ignores : [uri => uri.includes('#'),uri => uri === 'https://wangkejie.gitee.io/blogwebpage/page/6/',]
      });
      });
  </script>

</body>
</html>
